init_apic_ldr();
/*
- * Set Task Priority to 'accept all'. We never change this
- * later on.
+ * Set Task Priority to reject any interrupts below FIRST_DYNAMIC_VECTOR.
*/
- value = apic_read(APIC_TASKPRI);
- value &= ~APIC_TPRI_MASK;
- apic_write_around(APIC_TASKPRI, value);
+ apic_write_around(APIC_TASKPRI, (FIRST_DYNAMIC_VECTOR & 0xF0) - 0x10);
/*
* After a crash, we no longer service the interrupts and a pending
return 0;
}
+
+void check_for_unexpected_msi(unsigned int vector)
+{
+ unsigned long v = apic_read(APIC_ISR + ((vector & ~0x1f) >> 1));
+ BUG_ON(v & (1 << (vector & 0x1f)));
+}
#include <asm/page.h>
#include <asm/desc.h>
#include <public/xen.h>
+#include <irq_vectors.h>
ALIGN
ENTRY(compat_hypercall)
pushq $0
movl $TRAP_syscall,4(%rsp)
SAVE_ALL
+
+ cmpb $0,untrusted_msi(%rip)
+UNLIKELY_START(ne, msi_check)
+ movl $HYPERCALL_VECTOR,%edi
+ call check_for_unexpected_msi
+ RESTORE_ALL
+ SAVE_ALL
+UNLIKELY_END(msi_check)
+
GET_CURRENT(%rbx)
cmpl $NR_hypercalls,%eax
pushq $0
SAVE_ALL
+ cmpb $0,untrusted_msi(%rip)
+UNLIKELY_START(ne, msi_check)
+ movl $0x80,%edi
+ call check_for_unexpected_msi
+ RESTORE_ALL
+ SAVE_ALL
+UNLIKELY_END(msi_check)
+
GET_CURRENT(%rbx)
/* Check that the callback is non-null. */
#define nr_ioapics iosapic_get_nr_iosapics()
#endif
+/* Possible unfiltered LAPIC/MSI messages from untrusted sources? */
+bool_t __read_mostly untrusted_msi;
+
int nr_iommus;
static void setup_dom0_devices(struct domain *d);
if (!pdev)
return -ENODEV;
+ /*
+ * Devices assigned to untrusted domains (here assumed to be any domU)
+ * can attempt to send arbitrary LAPIC/MSI messages. We are unprotected
+ * by the root complex unless interrupt remapping is enabled.
+ */
+ if ( (target != dom0) && !iommu_intremap )
+ untrusted_msi = 1;
+
ret = domain_context_unmap(source, bus, devfn);
if ( ret )
return ret;